<template>
    <!-- 中间画布显示 -->
    <!-- @wheel="($event) => handleMousewheelCanvas($event)"
        @mousedown="($event) => handleClickBlankArea($event)" -->
      <div
        ref="canvasRef"
        class="canvas scroll-container"
        @mousedown="($event) => handleClickBlankArea($event)"
        v-contextmenu="contextmenus"
        v-click-outside="removeEditorAreaFocus"
      >
        <ElementCreateSelection
          v-if="creatingElement"
          @created="(data) => insertElementFromCreateSelection(data)"
        />

        <div
          class="viewport-wrapper"
          :style="{
            width: canvasWidth1 * canvasScale + 'px',
            height: canvasHeight1 * canvasScale + 'px',
            left: viewportStyles.left + 'px',
            top:   viewportStyles.top + 'px',
          }"
        >
          <div class="operates">
            <AlignmentLine
              v-for="(line, index) in alignmentLines"
              :key="index"
              :type="line.type"
              :axis="line.axis"
              :length="line.length"
              :canvasScale="canvasScale"
            />
            <MultiSelectOperate
              v-if="activeElementIdList.length > 1"
              :elementList="elementList"
              :scaleMultiElement="scaleMultiElement"
            />
            <Operate
              v-for="element in elementList"
              :key="element.id"
              :elementInfo="element"
              :isSelected="activeElementIdList.includes(element.id)"
              :isActive="handleElementId === element.id"
              :isActiveGroupElement="activeGroupElementId === element.id"
              :isMultiSelect="activeElementIdList.length > 1"
              :rotateElement="rotateElement"
              :scaleElement="scaleElement"
              :openLinkDialog="openLinkDialog"
              :dragLineElement="dragLineElement"
              :moveShapeKeypoint="moveShapeKeypoint"
              v-show="!hiddenElementIdList.includes(element.id)"
            />
            <ViewportBackground />
          </div>
          <div
            class="viewport"
            ref="viewportRef"
            :style="{ transform: `scale(${canvasScale})` }"
          >
            <MouseSelection
              v-if="mouseSelectionVisible"
              :top="mouseSelection.top"
              :left="mouseSelection.left"
              :width="mouseSelection.width"
              :height="mouseSelection.height"
              :quadrant="mouseSelectionQuadrant"
            />
            <EditableElement
              v-for="(element, index) in elementList"
              :key="element.id"
              :elementInfo="element"
              :elementIndex="index + 1"
              :isMultiSelect="activeElementIdList.length > 1"
              :selectElement="selectElement"
              :openLinkDialog="openLinkDialog"
              v-show="!hiddenElementIdList.includes(element.id)"
            />
          </div>
        </div>

        <div class="drag-mask" v-if="spaceKeyState"></div>
        <Ruler :viewportStyles="viewportStyles" v-if="showRuler" />

        <Modal
          v-model:visible="linkDialogVisible"
          :footer="null"
          centered
          :width="540"
          destroyOnClose
        >
          <LinkDialog @close="linkDialogVisible = false" />
        </Modal>
      </div>
</template>
<script lang="ts" setup>
import {
  nextTick,
  getCurrentInstance,
  onMounted,
  onUnmounted,
  provide,
  ref,
  watch,
  watchEffect,
  onBeforeUnmount,
} from "vue";
import { throttle } from "lodash";
import { storeToRefs } from "pinia";
import { useMainStore, useSlidesStore, useKeyboardStore } from "@/store";
import { ContextmenuItem } from "@/components/Contextmenu/types";
import { PPTElement } from "@/types/slides";
import { AlignmentLineProps } from "@/types/edit";
import { injectKeySlideScale } from "@/types/injectKey";
import { removeAllRanges } from "@/utils/selection";
import { KEYS } from "@/configs/hotkey";
import useViewportSize from "./hooks/useViewportSize";
import useMouseSelection from "./hooks/useMouseSelection";
import useDropImageOrText from "./hooks/useDropImageOrText";
import useRotateElement from "./hooks/useRotateElement";
import useScaleElement from "./hooks/useScaleElement";
import useSelectElement from "./hooks/useSelectElement";
import useDragElement from "./hooks/useDragElement";
import useDragLineElement from "./hooks/useDragLineElement";
import useMoveShapeKeypoint from "./hooks/useMoveShapeKeypoint";
import useInsertFromCreateSelection from "./hooks/useInsertFromCreateSelection";
import useDeleteElement from "@/hooks/useDeleteElement";
import useCopyAndPasteElement from "@/hooks/useCopyAndPasteElement";
import useSelectAllElement from "@/hooks/useSelectAllElement";
import useScaleCanvas from "@/hooks/useScaleCanvas";
import useScreening from "@/hooks/useScreening";
import useSlideHandler from "@/hooks/useSlideHandler";
import EditableElement from "./EditableElement.vue";
import MouseSelection from "./MouseSelection.vue";
import ViewportBackground from "./ViewportBackground.vue";
import AlignmentLine from "./AlignmentLine.vue";
import Ruler from "./Ruler.vue";
import ElementCreateSelection from "./ElementCreateSelection.vue";
import MultiSelectOperate from "./Operate/MultiSelectOperate.vue";
import Operate from "./Operate/index.vue";
import LinkDialog from "./LinkDialog.vue";
import { Modal } from "ant-design-vue";
import html2canvas from "html2canvas";
const mainStore = useMainStore();
const {
  activeElementIdList,
  activeGroupElementId,
  handleElementId,
  hiddenElementIdList,
  editorAreaFocus,
  gridLineSize,
  showRuler,
  showSelectPanel,
  creatingElement,
  canvasScale,
  textFormatPainter,
  eventIs,
  sharedData,
  canvasWidth1,
  canvasHeight1,
  recordW,
  recordH,
} = storeToRefs(mainStore);
const { currentSlide } = storeToRefs(useSlidesStore());
const { ctrlKeyState, spaceKeyState } = storeToRefs(useKeyboardStore());

const viewportRef = ref<HTMLElement>();
const alignmentLines = ref<AlignmentLineProps[]>([]);

const linkDialogVisible = ref(false);
const openLinkDialog = () => (linkDialogVisible.value = true);
watch(handleElementId, () => {
  mainStore.setActiveGroupElementId("");
});
const elementList = ref<PPTElement[]>([]);
const setLocalElementList = () => {
  try {
    elementList.value =
      currentSlide.value && currentSlide.value.elements
        ? JSON.parse(JSON.stringify(currentSlide.value.elements))
        : [];
  } catch (error) {}
};
watchEffect(setLocalElementList);
const canvasRef = ref<HTMLElement>();
const canvasImg = ref();
const savedContent = ref();
const savedImage = ref();
watch(eventIs, (newVal) => {
  saveImage();
});
const saveImage = async () => {
  // 这个saveImage事件然后我会拿到一个bas64 再传给后端
  // 用来保存这个画布，然后变成图片传个后端的所
  const element = canvasRef.value; // 获取保存的画面元素
  setTimeout(() => {
    html2canvas(element as HTMLElement, {
      useCORS: true,
      backgroundColor: null,
      logging: true,
    }).then((canvas) => {
      const imgUrl = canvas.toDataURL("image/png", 5.0);
      console.log(imgUrl);
    });
  }, 1000);
};
const { dragViewport, viewportStyles } = useViewportSize(canvasRef);
useDropImageOrText(canvasRef);
const {
  mouseSelection,
  mouseSelectionVisible,
  mouseSelectionQuadrant,
  updateMouseSelection,
} = useMouseSelection(elementList, viewportRef);

const { dragElement } = useDragElement(
  elementList,
  alignmentLines,
  canvasScale
);
const { dragLineElement } = useDragLineElement(elementList);
const { selectElement } = useSelectElement(elementList, dragElement);
const { scaleElement, scaleMultiElement } = useScaleElement(
  elementList,
  alignmentLines,
  canvasScale
);
const { rotateElement } = useRotateElement(elementList, viewportRef);
const { moveShapeKeypoint } = useMoveShapeKeypoint(elementList, canvasScale);

const { selectAllElement } = useSelectAllElement();
const { deleteAllElements } = useDeleteElement();
const { pasteElement } = useCopyAndPasteElement();
const { enterScreeningFromStart } = useScreening();
const { updateSlideIndex } = useSlideHandler();
// 组件渲染时，如果存在元素焦点，需要清除
// 这种情况存在于：有焦点元素的情况下进入了放映模式，再退出时，需要清除原先的焦点（因为可能已经切换了页面）
var canvasWidth = ref(500);
var addrouter = ref();
onMounted(() => {
  //     if(canvasWidth1.value >= canvasHeight.value || canvasHeight1.value>canvasWidth.value){
  //     canvasHeight.value = canvasWidth1.value = canvasHeight1.value * 1600 /canvasWidth1.value
  //     canvasWidth.value = 1600
  //   }else{
  //     canvasWidth.value = canvasWidth1.value  = canvasHeight1.value   * 900 / canvasHeight1.value
  //   canvasHeight.value = 900
  // //   addrouter.value = canvasHeight1.value * canvasScale.value + 'px'
  //   }
  let foundValue = false; // 标记是否找到合适的值

  while (!foundValue) {
    if (canvasWidth1.value == canvasHeight1.value) {
      addrouter.value = canvasHeight1.value * canvasScale.value + "px";
      foundValue = true; // 找到合适的值，退出循环
    } else if (canvasHeight1.value == canvasWidth1.value) {
      addrouter.value = canvasHeight1.value * canvasScale.value + "px";
      foundValue = true;
    } else if (canvasHeight1.value <= canvasWidth1.value) {
      addrouter.value = canvasHeight1.value * canvasScale.value + "px";
      foundValue = true;
    } else if (canvasHeight1.value >= canvasWidth1.value) {
      addrouter.value = canvasHeight1.value * canvasScale.value + "px";
      foundValue = true;
    } else if (canvasWidth1.value <= canvasHeight1.value) {
      addrouter.value = canvasHeight1.value * canvasScale.value + "px";
      foundValue = true;
    } else {
      addrouter.value = canvasHeight1.value * canvasScale.value + "px";
      foundValue = true;
    }
  }
  if (activeElementIdList.value.length) {
    nextTick(() => mainStore.setActiveElementIdList([]));
  }
});

// 点击画布的空白区域：清空焦点元素、设置画布焦点、清除文字选区、清空格式刷状态
const handleClickBlankArea = (e: MouseEvent) => {
  if (activeElementIdList.value.length) mainStore.setActiveElementIdList([]);

  if (!spaceKeyState.value) updateMouseSelection(e);
  else dragViewport(e);

  if (!editorAreaFocus.value) mainStore.setEditorareaFocus(true);
  if (textFormatPainter.value) mainStore.setTextFormatPainter(null);
  removeAllRanges();
};

// 画布注销时清空格式刷状态
onUnmounted(() => {
  if (textFormatPainter.value) mainStore.setTextFormatPainter(null);
});

// 移除画布编辑区域焦点
const removeEditorAreaFocus = () => {
  if (editorAreaFocus.value) mainStore.setEditorareaFocus(false);
};

// 滚动鼠标
const { scaleCanvas } = useScaleCanvas();
const throttleScaleCanvas = throttle(scaleCanvas, 100, {
  leading: true,
  trailing: false,
});
const throttleUpdateSlideIndex = throttle(updateSlideIndex, 300, {
  leading: true,
  trailing: false,
});

const handleMousewheelCanvas = (e: WheelEvent) => {
  e.preventDefault();

  // 按住Ctrl键时：缩放画布
  if (ctrlKeyState.value) {
    if (e.deltaY > 0) throttleScaleCanvas("-");
    else if (e.deltaY < 0) throttleScaleCanvas("+");
  }
  // 上下翻页
  else {
    if (e.deltaY > 0) throttleUpdateSlideIndex(KEYS.DOWN);
    else if (e.deltaY < 0) throttleUpdateSlideIndex(KEYS.UP);
  }
};

// 开关标尺
const toggleRuler = () => {
  mainStore.setRulerState(!showRuler.value);
};

// 在鼠标绘制的范围插入元素
const { insertElementFromCreateSelection } =
  useInsertFromCreateSelection(viewportRef);

const contextmenus = (): ContextmenuItem[] => {
  return [
    {
      text: "粘贴",
      subText: "Ctrl + V",
      handler: pasteElement,
    },
    {
      text: "全选",
      subText: "Ctrl + A",
      handler: selectAllElement,
    },
    {
      text: "标尺",
      subText: showRuler.value ? "√" : "",
      handler: toggleRuler,
    },
    {
      text: "网格线",
      handler: () => mainStore.setGridLineSize(gridLineSize.value ? 0 : 50),
      children: [
        {
          text: "无",
          subText: gridLineSize.value === 0 ? "√" : "",
          handler: () => mainStore.setGridLineSize(0),
        },
        {
          text: "小",
          subText: gridLineSize.value === 25 ? "√" : "",
          handler: () => mainStore.setGridLineSize(25),
        },
        {
          text: "中",
          subText: gridLineSize.value === 50 ? "√" : "",
          handler: () => mainStore.setGridLineSize(50),
        },
        {
          text: "大",
          subText: gridLineSize.value === 100 ? "√" : "",
          handler: () => mainStore.setGridLineSize(100),
        },
      ],
    },
    // {
    //   text: showSelectPanel.value ? '关闭选择面板' : '打开选择面板',
    //   handler: () => {
    //     if (!showSelectPanel.value) mainStore.setSelectPanelState(true)
    //     else mainStore.setSelectPanelState(false)
    //   },
    // },
    {
      text: "重置当前页",
      handler: deleteAllElements,
    },
    { divider: true },
    {
      text: "幻灯片放映",
      subText: "F5",
      handler: enterScreeningFromStart,
    },
  ];
};

provide(injectKeySlideScale, canvasScale);
</script>

<style lang="scss" scoped>
.canvas {
  height: 100%;
  user-select: none;
  overflow: hidden;
  background-color: #ededee;
  position: relative;

}
.drag-mask {
  cursor: grab;
  @include absolute-0();
}
.viewport-wrapper {

  position: absolute;
  box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.1);
  bottom: 20px;
  /* 父容器样式 */
}
.viewport {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 0 0;
}
::v-deep .viewport-background[data-v-7c6b7223] {
  width: 100%;
  height: 100%;
  background-position: center;
  position: absolute;
  bottom: 15px;
}
.scroll-container {
  overflow: auto;
  scrollbar-width: thin; /* 用于支持 Firefox */
  scrollbar-color: #888888 #f2f2f2; /* 滚动条颜色，第一个参数为滑块颜色，第二个参数为轨道颜色 */
}

/* WebKit 浏览器样式 */
.scroll-container::-webkit-scrollbar {
  width: 8px; /* 滚动条宽度 */
}

.scroll-container::-webkit-scrollbar-track {
  background-color: #f2f2f2; /* 轨道背景色 */
}

.scroll-container::-webkit-scrollbar-thumb {
  background-color: #888888; /* 滑块背景色 */
}

/* Firefox 浏览器样式 */
.scroll-container {
  scrollbar-color: #888888 #f2f2f2; /* 滚动条颜色，第一个参数为滑块颜色，第二个参数为轨道颜色 */
  scrollbar-width: thin; /* 滚动条宽度 */
}
</style>
